import router from 'umi/router';
import { getAnalysisModelDemestionLevel, reportDrillDown } from 'services/chartDetail';
import { chartData } from 'utils';
import { Toast, Modal } from 'antd-mobile';
import styles from './style.less';

const { dataParse, setOption } = chartData;
const { alert } = Modal;

// 自定义存储数据
const DataStorage = {
  // 初始数据
  baseData: {},
  // ID的堆栈
  keyStack: [],
  // 当前数据参数
  option: null,
  // 查过的数据缓存起来 以ID为键
  stackStore: new Map(),
  // 如果是char图时外框高度
  chartBoxMinHiehgt: 600,
  // 选中的柱子/饼/线/单元格

  // 上次点击的item
  selectItem: '',
};

/** ------操作栈----- */
const Stack = {
  addStack: data => {
    const key = Symbol('key');
    DataStorage.stackStore.set(key, data);
    return DataStorage.keyStack.push(key);
  },
  getStack: () => {
    // 直接查看堆栈最外层
    const topKey = DataStorage.keyStack[DataStorage.keyStack.length - 1 || 0];
    return DataStorage.stackStore.get(topKey) || {};
    /*
          {
            datas: [],  // 数据源
            ReprotName: null, // 报表名
            reporterType: null, // 图表类型
            measureList: [],  // 度量 列表
            dimensionList: [],   // 维度 列表
            legendData: [], // 图例列表
            dimensionAxis: [], // 主轴列表
          };
          */
  },
  deleteStack: () => {
    // 直接删除最外层的栈
    // 数据不易，暂时不删除
    return DataStorage.keyStack.pop();
  },
  isTopStack: () => DataStorage.keyStack.length <= 1,
  clearStack: () => {
    DataStorage.stackStore.clear();
    DataStorage.keyStack.length = 0;
  },
};
/** ------操作栈----- */

export default {
  namespace: 'chartDetail',
  state: {
    // 报表名
    ReprotName: null,
    time: null,
    // 当前度量(图表需要， 表格不用)
    currentMeasure: null,
    // 图表类型
    reporterType: null,

    // 度量 列表
    measureList: [],
    // 维度 列表
    dimensionList: [],
    option: {},
    parseData: {},
    isTop: true,
  },
  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(location => {
        if (location.pathname === '/chartDetail') {
          if (!location.state || !location.state.ID) {
            router.replace('/');
          }
          DataStorage.baseData = location.state;
          dispatch({ type: 'initialData', payload: location.state });
        }
      });
    },
  },
  effects: {
    *initialData({ payload }, { call, put }) {
      Stack.clearStack();
      yield put({
        type: 'refreshChart',
        payload: {
          data: payload,
        },
      });
    },
    // 获取渲染数据
    *refreshChart({ payload = {} }, { call, put, select }) {
      let { currentMeasure } = yield select(_ => _.chartDetail);
      const { data } = payload;
      let newCurrentMeasure = payload.currentMeasure || currentMeasure;
      // 清空选中
      DataStorage.selectItem = '';
      // loading
      setTimeout(() => {
        Toast.loading('正在渲染数据', 0.5);
      });
      let parseData = null;
      if (data) {
        parseData = dataParse(data);
        Stack.addStack(parseData);
      } else {
        // 没有数据或数据id时,看缓存中是否有
        parseData = Stack.getStack();
      }
      // 如果都没有就 返回不执行
      if (!parseData) {
        return console.warn('数据为空');
      }
      const option = setOption({
        parseData,
        currentMeasure: newCurrentMeasure,
      });

      yield put({
        type: 'updateState',
        payload: {
          time: new Date().getTime(),
          currentMeasure: newCurrentMeasure,
          option,
          parseData,
          isTop: Stack.isTopStack(),
        },
      });
    },

    // 选择度量
    *onSelectMeasureChange({ payload }, { put }) {
      // const { currentMeasure } = payload;
      yield put({ type: 'refreshChart', payload });
    },

    // 退回
    *goBack(_, { put }) {
      if (Stack.isTopStack()) {
        return router.push('/');
      }
      Stack.deleteStack();
      yield put({ type: 'refreshChart' });
    },
    // 点击 图表

    // 点击echart
    *chartPress({ payload }, { put }) {
      const { seriesName, name } = payload;
      const itemString = `${seriesName}-${name}`;
      if (DataStorage.selectItem !== itemString) {
        DataStorage.selectItem = itemString;
        return;
      }
      // {value, name }
      const parentDimensionValue = [name, seriesName];
      yield put({
        type: 'pressData',
        payload: parentDimensionValue,
      });
    },
    // 点击表格行
    *onTableRowPress({ payload = [] }, { put }) {
      const firstDimension = payload[0] && payload[0].Value;
      const secendDimension = payload[1] && payload[1].Value;
      const parentDimensionValue = [firstDimension, secendDimension];
      const itemString = `${firstDimension}-${secendDimension}`;
      if (DataStorage.selectItem !== itemString) {
        DataStorage.selectItem = itemString;
        return;
      }
      yield put({
        type: 'pressData',
        payload: parentDimensionValue,
      });
    },

    // 点击 echar或table
    *pressData({ payload: parentDimensionValue }, { put }) {
      const { dimensionList, DimensionValues = [], ConvertType, MacroType } = Stack.getStack();
      // ConvertType: 是否行列转置 不下穿
      if (ConvertType || Number(MacroType)) return;

      // {value, name }
      parentDimensionValue.length = dimensionList.length;

      yield put({
        type: 'getDemestionLevel',
        payload: {
          parentDimension: dimensionList.map(e => e.key),
          DimensionValues: [
            ...DimensionValues,
            ...dimensionList.map((e, index) => ({
              Dimension: e.key,
              DimensionValue: parentDimensionValue[index],
            })),
          ],
          parentDimensionValue,
        },
      });
    },

    // 获取 子层级 并准备下穿
    *getDemestionLevel({ payload }, { call, put }) {
      const { parentDimension, DimensionValues, parentDimensionValue } = payload;
      const { ModelID, ID, Measure } = DataStorage.baseData;
      const { data: FieldDataList = [] } = yield call(getAnalysisModelDemestionLevel, {
        FieldNames: parentDimension,
        ModelID,
      });
      const ChildFields = [];
      for (const filedData of FieldDataList) {
        if (!filedData || !filedData.ChildFields || !filedData.ChildFields.length) {
          continue;
        }
        for (const childField of filedData.ChildFields) {
          ChildFields.push(childField);
        }
      }

      if (!ChildFields.length) {
        // 如果下级层级为空 就返回
        return setTimeout(() => Toast.info('已经是最底层啦，无法继续下穿', 1));
      }
      if (ChildFields.length < 2) {
        yield put({
          type: 'drillDown',
          payload: {
            DimensionValues,
            parentDimensionValue,
            NewDimension: ChildFields[0].FieldName,
          },
        });
        return;
      }

      // 如果有多个下级维度就执行下面的代码
      return alert(
        '层级选择',
        <span style={[styles.markText]}>请选择下级层级!</span>,
        [
          ...ChildFields.map(d => ({
            text: <span>{d.DisplayName || d.FieldName}</span>,
            onPress: () => {
              window.g_app._store.dispatch({
                type: 'chartDetail/drillDown',
                payload: {
                  DimensionValues,
                  parentDimensionValue,
                  NewDimension: d.FieldName,
                },
              });
            },
          })),
          { text: <span style={[styles.markText]}>取消</span> },
        ],
        { cancelable: false }
      );
    },

    // 下穿
    *drillDown({ payload }, { call, put }) {
      const { parentDimension, DimensionValues, parentDimensionValue, NewDimension } = payload;
      const { ModelID, ID, Measure } = DataStorage.baseData;
      // const { data: ChildFieldNames = [] } = yield call(getAnalysisModelDemestionLevel, {
      //   FieldNames: [parentDimension],
      //   ModelID,
      // });

      // if (!ChildFieldNames || !ChildFieldNames.length) {
      //   // 如果子维度为空 就返回
      //   return setTimeout(() => Toast.info('已经是最底层啦，无法继续下穿', 2));
      // }

      const { data: newReporterData } = yield call(reportDrillDown, {
        DimensionValues,
        NewDimension,
        reporterID: ID,
        Measure,
        parentDimensionValue,
      });

      const newBaseData = {
        ...DataStorage.baseData, // 原来的基础数据
        DimensionValues, // 加入 DimensionValues 显示维度层级关系
        parentDimensionValue, // 保存上次的维度名
        DataJson: newReporterData || [], // 下穿获取的新数据替换旧数据
        Dimension: NewDimension, // 维度使用新维度
      };
      yield put({
        type: 'refreshChart',
        payload: {
          data: newBaseData,
        },
      });
    },
  },
  reducers: {
    updateState(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  },
};
